/*
 * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

/*
 * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved
 * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved
 *
 * The original version of this source code and documentation is
 * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary
 * of IBM. These materials are provided under terms of a License
 * Agreement between Taligent and Sun. This technology is protected
 * by multiple US and International patents.
 *
 * This notice and attribution to Taligent may not be removed.
 * Taligent is a registered trademark of Taligent, Inc.
 */

package java.awt.font;

/**
 * The <code>GlyphJustificationInfo</code> class represents information
 * about the justification properties of a glyph.  A glyph is the visual
 * representation of one or more characters.  Many different glyphs can
 * be used to represent a single character or combination of characters.
 * The four justification properties represented by
 * <code>GlyphJustificationInfo</code> are weight, priority, absorb and
 * limit.
 * <p>
 * Weight is the overall 'weight' of the glyph in the line.  Generally it is
 * proportional to the size of the font.  Glyphs with larger weight are
 * allocated a correspondingly larger amount of the change in space.
 * <p>
 * Priority determines the justification phase in which this glyph is used.
 * All glyphs of the same priority are examined before glyphs of the next
 * priority.  If all the change in space can be allocated to these glyphs
 * without exceeding their limits, then glyphs of the next priority are not
 * examined. There are four priorities, kashida, whitespace, interchar,
 * and none.  KASHIDA is the first priority examined. NONE is the last
 * priority examined.
 * <p>
 * Absorb determines whether a glyph absorbs all change in space.  Within a
 * given priority, some glyphs may absorb all the change in space.  If any of
 * these glyphs are present, no glyphs of later priority are examined.
 * <p>
 * Limit determines the maximum or minimum amount by which the glyph can
 * change. Left and right sides of the glyph can have different limits.
 * <p>
 * Each <code>GlyphJustificationInfo</code> represents two sets of
 * metrics, which are <i>growing</i> and <i>shrinking</i>.  Growing
 * metrics are used when the glyphs on a line are to be
 * spread apart to fit a larger width.  Shrinking metrics are used when
 * the glyphs are to be moved together to fit a smaller width.
 */

public final class GlyphJustificationInfo {

  /**
   * Constructs information about the justification properties of a
   * glyph.
   *
   * @param weight the weight of this glyph when allocating space.  Must be non-negative.
   * @param growAbsorb if <code>true</code> this glyph absorbs all extra space at this priority and
   * lower priority levels when it grows
   * @param growPriority the priority level of this glyph when it grows
   * @param growLeftLimit the maximum amount by which the left side of this glyph can grow.  Must be
   * non-negative.
   * @param growRightLimit the maximum amount by which the right side of this glyph can grow.  Must
   * be non-negative.
   * @param shrinkAbsorb if <code>true</code>, this glyph absorbs all remaining shrinkage at this
   * and lower priority levels when it shrinks
   * @param shrinkPriority the priority level of this glyph when it shrinks
   * @param shrinkLeftLimit the maximum amount by which the left side of this glyph can shrink.
   * Must be non-negative.
   * @param shrinkRightLimit the maximum amount by which the right side of this glyph can shrink.
   * Must be non-negative.
   */
  public GlyphJustificationInfo(float weight,
      boolean growAbsorb,
      int growPriority,
      float growLeftLimit,
      float growRightLimit,
      boolean shrinkAbsorb,
      int shrinkPriority,
      float shrinkLeftLimit,
      float shrinkRightLimit) {
    if (weight < 0) {
      throw new IllegalArgumentException("weight is negative");
    }

    if (!priorityIsValid(growPriority)) {
      throw new IllegalArgumentException("Invalid grow priority");
    }
    if (growLeftLimit < 0) {
      throw new IllegalArgumentException("growLeftLimit is negative");
    }
    if (growRightLimit < 0) {
      throw new IllegalArgumentException("growRightLimit is negative");
    }

    if (!priorityIsValid(shrinkPriority)) {
      throw new IllegalArgumentException("Invalid shrink priority");
    }
    if (shrinkLeftLimit < 0) {
      throw new IllegalArgumentException("shrinkLeftLimit is negative");
    }
    if (shrinkRightLimit < 0) {
      throw new IllegalArgumentException("shrinkRightLimit is negative");
    }

    this.weight = weight;
    this.growAbsorb = growAbsorb;
    this.growPriority = growPriority;
    this.growLeftLimit = growLeftLimit;
    this.growRightLimit = growRightLimit;
    this.shrinkAbsorb = shrinkAbsorb;
    this.shrinkPriority = shrinkPriority;
    this.shrinkLeftLimit = shrinkLeftLimit;
    this.shrinkRightLimit = shrinkRightLimit;
  }

  private static boolean priorityIsValid(int priority) {

    return priority >= PRIORITY_KASHIDA && priority <= PRIORITY_NONE;
  }

  /**
   * The highest justification priority.
   */
  public static final int PRIORITY_KASHIDA = 0;

  /**
   * The second highest justification priority.
   */
  public static final int PRIORITY_WHITESPACE = 1;

  /**
   * The second lowest justification priority.
   */
  public static final int PRIORITY_INTERCHAR = 2;

  /**
   * The lowest justification priority.
   */
  public static final int PRIORITY_NONE = 3;

  /**
   * The weight of this glyph.
   */
  public final float weight;

  /**
   * The priority level of this glyph as it is growing.
   */
  public final int growPriority;

  /**
   * If <code>true</code>, this glyph absorbs all extra
   * space at this and lower priority levels when it grows.
   */
  public final boolean growAbsorb;

  /**
   * The maximum amount by which the left side of this glyph can grow.
   */
  public final float growLeftLimit;

  /**
   * The maximum amount by which the right side of this glyph can grow.
   */
  public final float growRightLimit;

  /**
   * The priority level of this glyph as it is shrinking.
   */
  public final int shrinkPriority;

  /**
   * If <code>true</code>,this glyph absorbs all remaining shrinkage at
   * this and lower priority levels as it shrinks.
   */
  public final boolean shrinkAbsorb;

  /**
   * The maximum amount by which the left side of this glyph can shrink
   * (a positive number).
   */
  public final float shrinkLeftLimit;

  /**
   * The maximum amount by which the right side of this glyph can shrink
   * (a positive number).
   */
  public final float shrinkRightLimit;
}
